#! /usr/bin/env python3
#*************************************************************************\
# \file build_kernel_test
# \author  Neil Turton <neilt@amd.com>
#  \brief  Compile a kernel test executable.
#   \date  2020-09-22
#
#*************************************************************************/
#
###########################################################################
# Copyright (C) 2023, Advanced Micro Devices, Inc. All rights reserved.
# SPDX-License-Identifier: MIT
###########################################################################
import argparse
import json
import os
import os.path
import shlex
import subprocess
import sys

prog_name = sys.argv[0]
prog_dir = os.path.dirname(prog_name)
top_dir_rel = os.path.join(prog_dir, '../..')
top_dir = os.path.abspath(top_dir_rel)
sys.path.append(os.path.join(top_dir, 'py-lib'))
import project_defs
import tool_config

class app(object):
    def parse_args(self, argv):
        build_dir = os.path.join(top_dir, "build")

        p = argparse.ArgumentParser(
            description="Build an HLS csim executable."
        )

        p.add_argument('-b', '--build-dir', default=build_dir,
                       help='Set the build directory.')
        p.add_argument('-o', '--output', nargs=1,
                       help='Set the output filename.')
        p.add_argument('-v', '--verbose', default=False,
                       action="store_true",
                       help='Enable verbose output.')

        p.add_argument('inputs', nargs='+',
                       help='The names of the input files.')

        self.__args = p.parse_args(argv[1:])

    def read_config(self):
        self.__config = tool_config.config(os.path.join(top_dir, "build"), {});

    def add_inputs(self, args):
        inputs = self.__args.inputs
        if ( len(inputs) == 1 and inputs[0].endswith(".json") ):
            f = open(inputs[0], "r")
            info = json.load(f)
            f.close()
            thread_ids = [x['thread_id'] for x in info['stages']]

            dirname = os.path.dirname(inputs[0])
            args.append(os.path.join(dirname, "poll_thread.cc"))
            for tid in thread_ids:
                args.append(os.path.join(dirname, "stage_%s.cc" % (tid,)))
            return

        for input in self.__args.inputs:
            args.append(input)

    def run_compiler(self):
        args = [
            self.__config.get('CXX'),
            '-o', self.__args.output[0],
            '-I'+os.path.join(top_dir, "include"),
            '-I'+os.path.join(top_dir, "testing/support/include"),
            '-I'+self.__config.get('XILINX_VITIS_HLS')+'/include',
        ] + project_defs.CCFLAGS + project_defs.CXXFLAGS + [
            '-DDISABLE_MAX_HLS_STREAM_DEPTH_PRINT',
            '-Wno-unknown-pragmas',
            '-Wno-maybe-uninitialized',
            '-Wno-unused-but-set-variable',
            '-Wno-unused-variable',
            '-Wno-int-in-bool-context',
            '-Wno-sign-compare',
            '-Wno-uninitialized',
            '-Wno-class-memaccess',
            '-fno-var-tracking-assignments',
        ]
        self.add_inputs(args)
        for t,n in project_defs.lib_defs['test_harness']:
            if t == 'file':
                args.append(os.path.join(self.__args.build_dir, n))
            else:
                assert t == 'lib'
                args.append('-l'+n)

        if self.__args.verbose:
            print("Command: %s" % (" ".join(shlex.quote(x) for x in args)))
            sys.stdout.flush()

        rc = subprocess.call(args)
        if rc != 0:
            sys.stderr.write("%s: The compiler exited with code %s\n" %
                             (sys.argv[0], rc))
            sys.exit(1)

    def run(self, argv):
        self.parse_args(argv)
        self.read_config()
        self.run_compiler()
        return 0

sys.exit(app().run(sys.argv))

